package errors

import (
    "fmt"
    "runtime"
    "strings"
    "time"
    "sync"

    "kwdb-import/pkg/parser"
)

// ErrorType 定义错误类型
type ErrorType string

const (
	// 解析错误
	ParseError ErrorType = "PARSE_ERROR"
	// 转换错误
	ConversionError ErrorType = "CONVERSION_ERROR"
	// 数据库连接错误
	ConnectionError ErrorType = "CONNECTION_ERROR"
	// 数据库执行错误
	ExecutionError ErrorType = "EXECUTION_ERROR"
	// 配置错误
	ConfigError ErrorType = "CONFIG_ERROR"
	// 文件操作错误
	FileError ErrorType = "FILE_ERROR"
	// 验证错误
	ValidationError ErrorType = "VALIDATION_ERROR"
	// 网络错误
	NetworkError ErrorType = "NETWORK_ERROR"
	// 超时错误
	TimeoutError ErrorType = "TIMEOUT_ERROR"
	// 权限错误
	PermissionError ErrorType = "PERMISSION_ERROR"
	// 资源不足错误
	ResourceError ErrorType = "RESOURCE_ERROR"
	// 未知错误
	UnknownError ErrorType = "UNKNOWN_ERROR"
)

// Severity 定义错误严重程度
type Severity string

const (
	SeverityLow      Severity = "LOW"
	SeverityMedium   Severity = "MEDIUM"
	SeverityHigh     Severity = "HIGH"
	SeverityCritical Severity = "CRITICAL"
)

// KWDBError 自定义错误类型
type KWDBError struct {
	Type        ErrorType              `json:"type"`
	Message     string                 `json:"message"`
	Cause       error                  `json:"cause,omitempty"`
	Context     map[string]interface{} `json:"context,omitempty"`
	Severity    Severity               `json:"severity"`
	Timestamp   time.Time              `json:"timestamp"`
	StackTrace  string                 `json:"stack_trace,omitempty"`
	Retryable   bool                   `json:"retryable"`
	Suggestion  string                 `json:"suggestion,omitempty"`
	ErrorCode   string                 `json:"error_code,omitempty"`
}

// Error 实现error接口
func (e *KWDBError) Error() string {
	if e.Cause != nil {
		return fmt.Sprintf("%s: %s (caused by: %v)", e.Type, e.Message, e.Cause)
	}
	return fmt.Sprintf("%s: %s", e.Type, e.Message)
}

// Unwrap 支持errors.Unwrap
func (e *KWDBError) Unwrap() error {
	return e.Cause
}

// Is 支持errors.Is
func (e *KWDBError) Is(target error) bool {
	if t, ok := target.(*KWDBError); ok {
		return e.Type == t.Type
	}
	return false
}

// WithContext 添加上下文信息
func (e *KWDBError) WithContext(key string, value interface{}) *KWDBError {
	if e.Context == nil {
		e.Context = make(map[string]interface{})
	}
	e.Context[key] = value
	return e
}

// WithSuggestion 添加解决建议
func (e *KWDBError) WithSuggestion(suggestion string) *KWDBError {
	e.Suggestion = suggestion
	return e
}

// WithErrorCode 添加错误代码
func (e *KWDBError) WithErrorCode(code string) *KWDBError {
	e.ErrorCode = code
	return e
}

// IsRetryable 检查错误是否可重试
func (e *KWDBError) IsRetryable() bool {
	return e.Retryable
}

// GetSeverity 获取错误严重程度
func (e *KWDBError) GetSeverity() Severity {
	return e.Severity
}

// GetContext 获取上下文信息
func (e *KWDBError) GetContext() map[string]interface{} {
	return e.Context
}

// GetSuggestion 获取解决建议
func (e *KWDBError) GetSuggestion() string {
	return e.Suggestion
}

// NewError 创建新的KWDBError
func NewError(errorType ErrorType, message string) *KWDBError {
	return &KWDBError{
		Type:       errorType,
		Message:    message,
		Severity:   SeverityMedium,
		Timestamp:  time.Now(),
		StackTrace: getStackTrace(),
		Retryable:  false,
	}
}

// NewErrorWithCause 创建带原因的错误
func NewErrorWithCause(errorType ErrorType, message string, cause error) *KWDBError {
	return &KWDBError{
		Type:       errorType,
		Message:    message,
		Cause:      cause,
		Severity:   SeverityMedium,
		Timestamp:  time.Now(),
		StackTrace: getStackTrace(),
		Retryable:  false,
	}
}

// NewRetryableError 创建可重试的错误
func NewRetryableError(errorType ErrorType, message string) *KWDBError {
	return &KWDBError{
		Type:       errorType,
		Message:    message,
		Severity:   SeverityMedium,
		Timestamp:  time.Now(),
		StackTrace: getStackTrace(),
		Retryable:  true,
	}
}

// NewCriticalError 创建严重错误
func NewCriticalError(errorType ErrorType, message string) *KWDBError {
	return &KWDBError{
		Type:       errorType,
		Message:    message,
		Severity:   SeverityCritical,
		Timestamp:  time.Now(),
		StackTrace: getStackTrace(),
		Retryable:  false,
	}
}

// 具体错误创建函数

// NewParseError 创建解析错误
func NewParseError(message string, line int, column int) *KWDBError {
	err := NewError(ParseError, message)
	err.WithContext("line", line)
	err.WithContext("column", column)
	err.WithSuggestion("请检查SQL语法是否正确")
	return err
}

// NewParseErrorWithSQL 创建带SQL内容的解析错误
func NewParseErrorWithSQL(message string, sql string, stmtType parser.StatementType) *KWDBError {
	err := NewError(ParseError, message)
	err.WithContext("sql", sql)
	err.WithContext("statement_type", stmtType)
	err.WithSuggestion("请检查SQL语句格式是否符合标准")
	return err
}

// NewConversionError 创建转换错误
func NewConversionError(message string, sourceType string, targetType string) *KWDBError {
	err := NewError(ConversionError, message)
	err.WithContext("source_type", sourceType)
	err.WithContext("target_type", targetType)
	err.WithSuggestion("请检查数据类型转换规则")
	return err
}

// NewConnectionError 创建连接错误
func NewConnectionError(message string, host string, port int) *KWDBError {
	err := NewRetryableError(ConnectionError, message)
	err.WithContext("host", host)
	err.WithContext("port", port)
	err.WithSuggestion("请检查数据库服务是否正常运行，网络连接是否正常")
	return err
}

// NewExecutionError 创建执行错误
func NewExecutionError(message string, sql string) *KWDBError {
	err := NewError(ExecutionError, message)
	err.WithContext("sql", sql)
	err.WithSuggestion("请检查SQL语句是否正确，数据库权限是否足够")
	return err
}

// NewConfigError 创建配置错误
func NewConfigError(message string, configKey string, configValue interface{}) *KWDBError {
	err := NewError(ConfigError, message)
	err.WithContext("config_key", configKey)
	err.WithContext("config_value", configValue)
	err.WithSuggestion("请检查配置文件格式和配置项的有效性")
	return err
}

// NewFileError 创建文件错误
func NewFileError(message string, filePath string, operation string) *KWDBError {
	err := NewError(FileError, message)
	err.WithContext("file_path", filePath)
	err.WithContext("operation", operation)
	err.WithSuggestion("请检查文件路径是否正确，文件权限是否足够")
	return err
}

// NewValidationError 创建验证错误
func NewValidationError(message string, field string, value interface{}) *KWDBError {
    err := NewError(ValidationError, message)
    err.WithContext("field", field)
    err.WithContext("value", value)
    err.WithSuggestion("请检查输入参数的格式和范围")
    return err
}

// IsValidationError 判断错误是否为验证错误类型
func IsValidationError(err error) bool {
    if err == nil {
        return false
    }
    if kwdbErr, ok := err.(*KWDBError); ok {
        return kwdbErr.Type == ValidationError
    }
    return false
}

// NewTimeoutError 创建超时错误
func NewTimeoutError(message string, timeout time.Duration, operation string) *KWDBError {
	err := NewRetryableError(TimeoutError, message)
	err.WithContext("timeout", timeout.String())
	err.WithContext("operation", operation)
	err.WithSuggestion("请考虑增加超时时间或检查网络连接")
	return err
}

// NewPermissionError 创建权限错误
func NewPermissionError(message string, resource string, action string) *KWDBError {
	err := NewError(PermissionError, message)
	err.WithContext("resource", resource)
	err.WithContext("action", action)
	err.WithSuggestion("请检查用户权限设置")
	return err
}

// NewResourceError 创建资源错误
func NewResourceError(message string, resourceType string, limit interface{}) *KWDBError {
	err := NewRetryableError(ResourceError, message)
	err.WithContext("resource_type", resourceType)
	err.WithContext("limit", limit)
	err.WithSuggestion("请检查系统资源使用情况，考虑优化或增加资源")
	return err
}

// 错误检查函数

// IsParseError 检查是否为解析错误
func IsParseError(err error) bool {
	if kwdbErr, ok := err.(*KWDBError); ok {
		return kwdbErr.Type == ParseError
	}
	return false
}

// IsConversionError 检查是否为转换错误
func IsConversionError(err error) bool {
	if kwdbErr, ok := err.(*KWDBError); ok {
		return kwdbErr.Type == ConversionError
	}
	return false
}

// IsConnectionError 检查是否为连接错误
func IsConnectionError(err error) bool {
	if kwdbErr, ok := err.(*KWDBError); ok {
		return kwdbErr.Type == ConnectionError
	}
	return false
}

// IsExecutionError 检查是否为执行错误
func IsExecutionError(err error) bool {
	if kwdbErr, ok := err.(*KWDBError); ok {
		return kwdbErr.Type == ExecutionError
	}
	return false
}

// IsRetryableError 检查错误是否可重试
func IsRetryableError(err error) bool {
	if kwdbErr, ok := err.(*KWDBError); ok {
		return kwdbErr.Retryable
	}
	return false
}

// IsCriticalError 检查是否为严重错误
func IsCriticalError(err error) bool {
	if kwdbErr, ok := err.(*KWDBError); ok {
		return kwdbErr.Severity == SeverityCritical
	}
	return false
}

// 错误聚合和统计

// ErrorStats 错误统计
type ErrorStats struct {
    TotalErrors   int                    `json:"total_errors"`
    ErrorsByType  map[ErrorType]int      `json:"errors_by_type"`
    ErrorsBySeverity map[Severity]int    `json:"errors_by_severity"`
    RetryableErrors int                  `json:"retryable_errors"`
    CriticalErrors  int                  `json:"critical_errors"`
    LastError     *KWDBError             `json:"last_error,omitempty"`
    StartTime     time.Time              `json:"start_time"`
    mu            sync.Mutex
}

// NewErrorStats 创建错误统计
func NewErrorStats() *ErrorStats {
	return &ErrorStats{
		ErrorsByType:     make(map[ErrorType]int),
		ErrorsBySeverity: make(map[Severity]int),
		StartTime:        time.Now(),
	}
}

// AddError 添加错误到统计
func (s *ErrorStats) AddError(err error) {
    s.mu.Lock()
    defer s.mu.Unlock()
    if kwdbErr, ok := err.(*KWDBError); ok {
        s.TotalErrors++
        s.ErrorsByType[kwdbErr.Type]++
        s.ErrorsBySeverity[kwdbErr.Severity]++
		
		if kwdbErr.Retryable {
			s.RetryableErrors++
		}
		
		if kwdbErr.Severity == SeverityCritical {
			s.CriticalErrors++
		}
		
		s.LastError = kwdbErr
	} else {
		// 处理非KWDBError类型的错误
		s.TotalErrors++
		s.ErrorsByType[UnknownError]++
		s.ErrorsBySeverity[SeverityMedium]++
	}
}

// GetErrorRate 获取错误率
func (s *ErrorStats) GetErrorRate() float64 {
	duration := time.Since(s.StartTime)
	if duration.Seconds() == 0 {
		return 0
	}
	return float64(s.TotalErrors) / duration.Seconds()
}

// GetMostCommonErrorType 获取最常见的错误类型
func (s *ErrorStats) GetMostCommonErrorType() ErrorType {
	maxCount := 0
	var mostCommon ErrorType
	
	for errorType, count := range s.ErrorsByType {
		if count > maxCount {
			maxCount = count
			mostCommon = errorType
		}
	}
	
	return mostCommon
}

// Reset 重置统计
func (s *ErrorStats) Reset() {
    s.mu.Lock()
    defer s.mu.Unlock()
    s.TotalErrors = 0
    s.ErrorsByType = make(map[ErrorType]int)
    s.ErrorsBySeverity = make(map[Severity]int)
    s.RetryableErrors = 0
    s.CriticalErrors = 0
    s.LastError = nil
    s.StartTime = time.Now()
}

// 工具函数

// getStackTrace 获取堆栈跟踪
func getStackTrace() string {
	buf := make([]byte, 1024)
	n := runtime.Stack(buf, false)
	return string(buf[:n])
}

// WrapError 包装标准错误为KWDBError
func WrapError(err error, errorType ErrorType, message string) *KWDBError {
	if err == nil {
		return nil
	}
	
	// 如果已经是KWDBError，直接返回
	if kwdbErr, ok := err.(*KWDBError); ok {
		return kwdbErr
	}
	
	return NewErrorWithCause(errorType, message, err)
}

// FormatError 格式化错误信息用于显示
func FormatError(err error) string {
	if kwdbErr, ok := err.(*KWDBError); ok {
		var parts []string
		
		// 基本信息
		parts = append(parts, fmt.Sprintf("[%s] %s", kwdbErr.Type, kwdbErr.Message))
		
		// 时间戳
		parts = append(parts, fmt.Sprintf("时间: %s", kwdbErr.Timestamp.Format("2006-01-02 15:04:05")))
		
		// 严重程度
		parts = append(parts, fmt.Sprintf("严重程度: %s", kwdbErr.Severity))
		
		// 上下文信息
		if len(kwdbErr.Context) > 0 {
			contextParts := make([]string, 0, len(kwdbErr.Context))
			for key, value := range kwdbErr.Context {
				contextParts = append(contextParts, fmt.Sprintf("%s=%v", key, value))
			}
			parts = append(parts, fmt.Sprintf("上下文: %s", strings.Join(contextParts, ", ")))
		}
		
		// 解决建议
		if kwdbErr.Suggestion != "" {
			parts = append(parts, fmt.Sprintf("建议: %s", kwdbErr.Suggestion))
		}
		
		// 是否可重试
		if kwdbErr.Retryable {
			parts = append(parts, "此错误可以重试")
		}
		
		return strings.Join(parts, "\n")
	}
	
	return err.Error()
}

// GetErrorSuggestion 根据错误类型获取通用建议
func GetErrorSuggestion(errorType ErrorType) string {
	suggestions := map[ErrorType]string{
		ParseError:      "请检查SQL语法是否正确，确保语句符合标准格式",
		ConversionError: "请检查数据类型转换规则，确保源类型和目标类型兼容",
		ConnectionError: "请检查数据库服务状态、网络连接和连接参数",
		ExecutionError:  "请检查SQL语句正确性、数据库权限和数据完整性",
		ConfigError:     "请检查配置文件格式和配置项的有效性",
		FileError:       "请检查文件路径、文件权限和磁盘空间",
		ValidationError: "请检查输入参数的格式、范围和必填项",
		NetworkError:    "请检查网络连接状态和防火墙设置",
		TimeoutError:    "请考虑增加超时时间或优化操作性能",
		PermissionError: "请检查用户权限和访问控制设置",
		ResourceError:   "请检查系统资源使用情况，考虑优化或扩容",
		UnknownError:    "请联系技术支持获取帮助",
	}
	
	if suggestion, exists := suggestions[errorType]; exists {
		return suggestion
	}
	return "请检查相关配置和环境设置"
}